package cn.ronghuanet.car.service.impl;

import cn.ronghuanet.base.service.impl.BaseServiceImpl;
import cn.ronghuanet.car.domain.CarType;
import cn.ronghuanet.car.mapper.CarTypeMapper;
import cn.ronghuanet.car.service.ICarTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xiong
 * @since 2023-06-30
 */
//@Service
public class CarTypeServiceImpl_原始版本 extends BaseServiceImpl<CarType> implements ICarTypeService {

    @Autowired
    private CarTypeMapper carTypeMapper;

    /**
     * 查询车辆类型树
     * 方案一: 递归  查询n+1次数据库
     * 方案二:循环   查询1次数据库  ->  对于数据库的压力更小
     * 不是说递归方案不能使用,而是递归方案不适合用在要查询数据库的时候
     * @return
     */
    @Override
    public List<CarType> tree(Long pid) {
        return getCarTypesByLoop(pid);
    }

    /**
     * 循环方案实现类型树查询  查询1次数据库
     * @param pid
     * @return
     */
    private List<CarType> getCarTypesByLoop(Long pid){
        // 1 查询出所有的车辆类型
        List<CarType> carTypes = carTypeMapper.selectAll();
        // 将所有的车辆类型放入map中,以类型的id作为key,以类型对象作为Value存入map
        Map<Long,CarType> map = new HashMap<>();
        for (CarType carType : carTypes) {
            map.put(carType.getId(),carType);
        }

        // 定义要返回的集合 - 它放的是一级类型
        List<CarType> result = new ArrayList<>();

        // 2 循环所有的车辆类型
        for (CarType carType : carTypes) {
            // 2.1 如果pid=0,将它放入要返回的集合中
            if(carType.getPid().longValue() == pid.longValue()){
                result.add(carType);
            }else{
                // 2.2 如果pid != 0,找到它的父类型,将自己作为父类型的子类型放进去
                // 方案一:父类型也在所有的类型中,所以循环所有的类型,判断carType.getPid == 类型.id,就说明这是它的父类型
                //  时间复杂度:  n*n次  简单理解:代码中的循环次数
                /*for (CarType parent : carTypes) {
                    if(carType.getPid().longValue() == parent.getId().longValue()){
                        // 将自己放入父类型的子集合里面
                        parent.getChildren().add(carType);
                        break;      // 如果都找到自己的父类型的话,没必要继续往下循环的
                    }
                }*/
                // 方案二:从map中取得父类型   时间复杂度:2n次
                CarType parent = map.get(carType.getPid());
                parent.getChildren().add(carType);
            }
        }
        return result;
    }

    /**
     * 递归方案实现类型树查询
     * @param pid
     * @return
     */
    private List<CarType> getCarTypesByRecursion(Long pid) {
        // 1 查询出所有的一级类型
        List<CarType> carTypes = carTypeMapper.loadByPid(pid);
        // 如果没有子类型,返回null
        if(carTypes == null || carTypes.size() == 0){
            return null;
        }
        for (CarType carType : carTypes) {
            // 循环父类型,以父类型的ID作为pid,查询它下面的子类型
            List<CarType> childs = tree(carType.getId());
            carType.setChildren(childs);
        }
        return carTypes;
    }
}
